﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Runtime.InteropServices;
using System.Management;
using System.Data.SqlClient;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Collections;
using System.Windows.Input;

//1、输出电流 100欧姆-- - 已经解决
//2、充电电流 100欧姆并联470欧姆-- - 已经解决
//3、温度优化，temp1,温度25.temp2温度23 或者63℃----已经解决
//4、如果没有串口将会死机。---已经解决
//5、文件增加了LOGO-2021.12.21
//6、将窗体的名字修改为PS-A3616测试-2021.12.21
//7、设置窗体的最大数值-2021.12.21
//8、串口事件接收前增加延时100ms, 保证接收数据的完整性。
//9、优化左下角的发送和接收。
//10、CheckFlag标志位增加，数据处理的时候不能清空q.Clear()，不然有可能清空正在处理的数据。2021.12.22
//11、PS - A3616 - V1.1Beta1 - FHSJ - tao，版本识别，需要更新
//        -------------------------------------------------------------------------------------------------- -
//        12、将软件修改成A型应急照明集中电源控制器测试开关电源部分。
//13、修改了校验方式，之前是和校验，后面改成CRC16校验
//14、版本识别修改，有两种长度33字节和36字节，33字节是锂电，36字节是铅酸。
//15、2022.7.25,每次发送之前将数据缓存清空，判定缓冲区大于24个则跳至下一步，小于24则延时50ms
//16、将上位机修改成1000W电源测试，
//17、软件版本信息修改(26个字节):
//PS-A3628-V1.0Beta3-SJ-tao\0
//50 53 2D 41 33 36 32 38 2D 56 31 2E 30 42 65 74 61 33 2D 53 4A 2D 74 61 6F 00 

namespace SimpleSerialPort
{
    public partial class Form1 : Form
    {

        /// 接收数据标志。
        /// </summary>
        bool IsReceving = false;// 处理字符串标志。   
        bool DoingHex = false;
        bool IsLIION = false;//判断是锂电还是铅酸标志位，IsLIION=true是锂电
        bool isOpen = false;//打开串口标志位
        int SendLen = 0;//发送统计
        int RecLen = 0;//接收统计    
        bool OnLine = false;
        bool overtemp = false;//过温标志     
        UInt32 TestFlag = 0;//产品故障测试的状态     
        System.DateTime dt;
        UInt16 TestCount = 0;//测试统计
        UInt16 TestOK = 0;//测试通过统计
        byte Rlen = 0;//接收的长度判定
        byte EmergencyFlag = 0;
        bool StartEmergency = false;//设置标志位，只进行一次应急
        bool EmergencyOK= false;//设置标志位，只进行一次应急
        bool OverEmergency = false;//设置标志位，只进行一次应急
        byte BatCheckCounts = 0;//检测电池在线计数
        bool BatOnLine = false;
        byte RecDataLength = 0;//接收数据帧的长度
        byte DataLength = 0;//接收数据帧的长度
        string goalPvison1 = "";//软件版本

        System.DateTime starttime;//开始测试的时间

        Queue<byte> q = new Queue<byte>(4096);//建立缓冲区接收数据

        [DllImport("kernel32.dll")]
        private static extern long WritePrivateProfileString(string section, string key, string value, string filepath);

        [DllImport("kernel32.dll")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder returnvalue, int buffersize, string filepath);
        public string IniFilePath = "";

        //新创建的INI文件的名字和路径
        //string newnamePath = Application.StartupPath + "\\" + tbox35.Text + ".ini";//version
        string newnamePath = System.Windows.Forms.Application.ExecutablePath + "Version.ini";//       
        byte[] Compare = new byte[14];
        public Form1()
        {
            InitializeComponent();
            this.Size = new Size(1275, 789);
            Control.CheckForIllegalCrossThreadCalls = false;
            goalPvison1 = GetValue("Information", "Version1", newnamePath); //通过INI文件获取锂电版本信息
            //goalPvison2 = GetValue("Information", "Version2", newnamePath); //通过INI文件获取铅酸版本信息
            //if (checkBox2.Checked)//如果是选中的,那就是锂电
            //    textBox32.Text = GetValue("Information", "Version1", newnamePath); //通过INI文件获取到文件版本信息
            //else
            //    textBox32.Text = GetValue("Information", "Version2", newnamePath);

        }

        private string GetValue(string section, string key, string IniFilePath)
        {
            StringBuilder stringBuilder = new StringBuilder();
            GetPrivateProfileString(section, key, "", stringBuilder, 1024, IniFilePath);
            return stringBuilder.ToString();
        }



        //查询版本信息：  P  S  -  A  3  6  1  6  -  V  1  .  0  B  e  a  t  1
        //版本信息对的HEX:50 53 2D 41 33 36 31 36 2D 56 31 2E 30 42 65 61 74 31
        /// <summary>
        /// 页面初始化,
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //加载串口                      
            timer1.Enabled = false;
        }

        /// <summary>
        /// 创建新的线程
        /// </summary>
        public void Start()//启动
        {
            Thread thread = new Thread(threadStart);
            thread.IsBackground = true;//后台运行
            thread.Start();
        }
        private void threadStart()
        {
            while (true)
            {
                //正常来说只有4种长度的回复 33,36是版本信息 35是标定信息，29是正常查询信息
                //if ((q.Count == 36) || (q.Count == 33)|| (q.Count == 38) || (q.Count == 28))
                    if (q.Count>0)
                    {                 
                    try
                    {
                       
                        ScanQueue1();
                    }
                    catch
                    {                        
                    }

                }
                else
                {
                    // label5.Text = RecLen.ToString();
                    Thread.Sleep(20);
                }
            }
        }


        int rec_i = 0;
        /// <summary>
        /// 要执行的方法
        /// </summary>
        //
        private void ScanQueue1()
        {
            byte[] data = new byte[38];//完整版的结果查询,不完整的版本是28个字节

            //50 53 2D 42 33 36 30 38 2D 4C 49 2D 49 4F 4E 2D 56 31 2E 30 42 65 74 61 33 2D 53 4A 2D 74 61 6F 00 
            byte[] vison = new byte[36];
            //版本信息1,总长33个字节，主要取前面25个字节：PS-B3608-LI-ION-V1.0Beta3
            //版本信息2,总长36个字节，主要取前面28个字节：PS-B3608-LEAD_ACID-V1.0Beta3

            byte RecCounts = 0;
            byte Recdata = 0;
            byte CRC16H = 0;//
            byte CRC16L = 0;//
            byte Alarm1 = 0;
            byte Alarm2 = 0;
            byte Alarm3 = 0;
            byte errflag = 0;
            UInt16 Calibration5V = 0;
            string StringRec = string.Empty;

            while (q.Count > 0)
            {


                try
                {
                   
                    if (QueryVersion)//如果版本结果已经查询到       
                    {
                        switch (rec_i)
                        {
                            case 0:
                                if (q.Dequeue() == 0xeb)//帧开头
                                {
                                    rec_i = 1;
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 1:
                                if (q.Dequeue() == 0x91)//帧开头
                                {
                                    rec_i = 2;
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 2:
                                 Recdata = q.Dequeue();
                                // RecDataLength = Recdata;
                                if (Recdata == 0x21|| Recdata == 0x17)
                                {
                                    RecCounts = Recdata;//接收的长度信息给全局变量                                                                 
                                    if(q.Count>24)
                                    { 
                                        rec_i = 3;                                       
                                    }
                                    else
                                    {
                                        Thread.Sleep(50);
                                    }

                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 3:
                                    OnLine = true;
                                    data[0] = RecCounts;
                                    Rlen = RecCounts;//将接收的数据的长度给全局变量
                                    DataLength = RecCounts;//需要校验的长度
                                    if (tbxSendStr.TextLength > 600)
                                        tbxSendStr.Text = "";
                                    for (int i = 1; i < RecCounts + 1; i++)//需要校验的数据
                                    {
                                        if (q.Count > 0)
                                            data[i] = q.Dequeue();
                                        string tempstr = data[i].ToString("X2");
                                        if (tempstr.Length < 2)
                                        {
                                            tempstr = '0' + tempstr;
                                        }
                                        StringRec += tempstr + ' ';
                                    }
                                    if (q.Count > 0)
                                        CRC16L = q.Dequeue();//接收到的校验字节低 
                                    if (q.Count > 0)
                                        CRC16H = q.Dequeue();//接收到的校验字节低 



                                    StringRec = StringRec.ToUpper();
                                    StringRec = "EB 91 " + RecCounts.ToString("X2") + " " + StringRec + CRC16L.ToString("X2") + " " + CRC16H.ToString("X2");
                            


                                    int CRC16_C = CRC_GetModbus16(data, RecCounts + 1);
                                    if ((CRC16L == (CRC16_C & 0xff)) && (CRC16H == (CRC16_C >> 8)))
                                    {
                                       tbxSendStr.AppendText(Environment.NewLine + StringRec);
                                       RecDataLength = RecCounts;
                                        if (byteToUInt16(data[2], data[3]) > 1700 && byteToUInt16(data[8], data[9]) > 210 && byteToUInt16(data[8], data[9]) < 280)
                                        {
                                            BatCheckCounts++;
                                            if (BatCheckCounts > 2)//连续在线，认为在线
                                            {
                                                BatOnLine = true;
                                            }
                                        }
                                        else
                                        {
                                            BatCheckCounts = 0;
                                        }

                                        //市电判定
                                        if (byteToUInt16(data[2], data[3]) > 1700 && byteToUInt16(data[2], data[3]) < 2400)
                                        {
                                            textBox1.Text = (byteToUInt16(data[2], data[3]) / 10.0).ToString("0.0");//ACV:交流电压，2字节，放大10倍
                                            textBox1.BackColor = Color.LawnGreen;
                                            TestFlag |= 0x00000100;
                                           // ProcuctValue |= 0x01;
                                        }

                                        textBox2.Text = (byteToUInt16(data[4], data[5]) / 10.0).ToString("0.0");//OUTV:输出电压，2字节，放大10倍

                                        //获取版本中的输出电压数值
                                        string Pvisonjiequ = textBox32.Text.Substring(4, 2);
                                        //得到版本的电压数值并放大10倍
                                        UInt16 dianya = (UInt16)((Convert.ToInt32(Pvisonjiequ) - 1) * 10);
                                        //textBox19.Text = dianya.ToString();
                                        //判定获取的数值大于版本的电压数值
                                        if (byteToUInt16(data[4], data[5]) > dianya)
                                        {
                                            
                                            TestFlag |= 0x00000200;
                                            textBox2.BackColor = Color.LawnGreen;
                                        }
                                        else
                                        {
                                            textBox2.BackColor = Color.Red;
                                           // TestFlag &= 0x0000fd00;
                                           
                                        }
                                        //输出电流范围0-0.6A
                                        if (byteToUInt16(data[6], data[7]) > 0 && byteToUInt16(data[6], data[7]) < 6)
                                        {
                                           //ProcuctValue |= 0x04;
                                            TestFlag |= 0x00000400;
                                            textBox3.Text = (byteToUInt16(data[6], data[7]) / 10.0).ToString("0.0");//OUTI: 输出电流，2字节，放大10倍
                                            textBox3.BackColor = Color.LawnGreen;
                                        }



                                        textBox4.Text = (byteToUInt16(data[8], data[9]) / 10.0).ToString("0.0");//BATV: 电池总电压，2字节，放大10倍
                                        if (byteToUInt16(data[8], data[9]) > 200 && byteToUInt16(data[8], data[9]) < 230)//
                                        {
                                            if (overtemp)
                                            {
                                                TestFlag |= 0x00000800;
                                                textBox4.BackColor = Color.LawnGreen;
                                            }
                                        }
                                        else
                                        {
                                            textBox4.BackColor = Color.White;
                                            //TestFlag &= 0x0000f700;                                           

                                       }


                                      
                                        textBox5.Text = (byteToUInt16(data[10], data[11]) / 10.0).ToString("0.0");//BATV1:电池1电压,  2字节, 放大10倍
                                        if (IsLIION | (byteToUInt16(data[10], data[11]) > 90 && byteToUInt16(data[10], data[11]) < 140))//电池温度
                                        {
                                            if (overtemp)
                                            {
                                                //ProcuctValue |= 0x10;
                                                TestFlag |= 0x00001000;
                                                textBox5.BackColor = Color.LawnGreen;
                                            }
                                        }
                                        else
                                        {
                                            textBox5.BackColor = Color.White;
                                            //TestFlag &= 0x0000ef00;
                                            //ProcuctValue &= 0xef;

                                        }

                                        //如果是锂电，则电池2不判定，默认通过
                                        textBox6.Text = (byteToUInt16(data[12], data[13]) / 10.0).ToString("0.0");//BATV2:电池2电压（最低节）,  2字节, 放大10倍
                                        if ( (byteToUInt16(data[12], data[13]) > 90 && byteToUInt16(data[12], data[13]) < 140))
                                        {
                                            //ProcuctValue |= 0x20;
                                            if (overtemp)
                                            {
                                                TestFlag |= 0x00002000;
                                                textBox6.BackColor = Color.LawnGreen;
                                            }
                                        }                                  



                                        textBox7.Text = (byteToUInt16(data[14], data[15])).ToString("0.0");//电池1温度, 2字节, 放大1倍
                                        if (byteToUInt16(data[14], data[15]) > 38 && byteToUInt16(data[14], data[15]) < 45)//电池温度
                                        {
                                            //ProcuctValue |= 0x40;
                                            if(overtemp)
                                            {
                                                TestFlag |= 0x00004000;
                                                textBox7.BackColor = Color.LawnGreen;
                                            }
                                        }
                                        else
                                        {
                                            textBox7.BackColor = Color.White;
                                            //TestFlag &= 0x0000bf00;
                                            //ProcuctValue &= 0xbf;
                                        }



                                        //充电电流0.2-0.4
                                        if (byteToUInt16(data[16], data[17]) > 0 && byteToUInt16(data[16], data[17]) < 5)
                                        {
                                           //ProcuctValue |= 0x80;
                                            TestFlag |= 0x00008000;
                                            textBox9.Text = (byteToUInt16(data[16], data[17]) / 10.0).ToString("0.0");//充电电流,2字节,放大10倍
                                            textBox9.BackColor = Color.LawnGreen;
                                        }
                                        //充电电压
                                        if (byteToUInt16(data[18], data[19]) > 0)
                                        {

                                            textBox11.Text = (byteToUInt16(data[18], data[19]) / 10.0).ToString("0.0");//充电电压1,2字节,放大10倍
                                            textBox11.BackColor = Color.LawnGreen;
                                        }

                                        Alarm1 = data[20];
                                        Alarm2 = data[21];
                                        Alarm3 = data[22];
                                        errflag = data[23];//简约版本只有前面23个字节 data[24]CRCL data[25]CRCh 
                                                           //data[24]//Power_State


                                        if (RecCounts == 0x21)//需要校验的数据31个
                                        {


                                            textBox20.Text = data[25].ToString();  //AC_Calib                                                                                      
                                            Calibration5V = byteToUInt16(data[26], data[27]);
                                            textBox30.Text = Calibration5V.ToString();//5V标定结果显示  //标定的结果判定                                                                                    
                                            if (Calibration5V > 4790 && Calibration5V < 5220)//
                                            {

                                                 TestFlag |= 0x00000002;//5V的标定标志位                                                
                                                 textBox30.BackColor = Color.LawnGreen;
                                            }
                                            else
                                            {
                                                textBox30.BackColor = Color.Red;
                                            }

                                            // textBox10.Text= (byteToUInt16(data[13], data[14])).ToString("0.0");//电池2温度, 2字节, 放大1倍 
                                            int Power_Temp = (byteToUInt16(data[28], data[29]));
                                            double temp100 = (1 / (Math.Log((2.0 * 4096 / Power_Temp - 2.0) * 1000 / 50000) / 3950 + 1 / (25 + 273.15)) - 273.15);//Power_Temp853 

                                            textBox8.Text = temp100.ToString("0.0");
                                            if (temp100 > 15 && temp100 < 40)
                                            {
                                                TestFlag |= 0x00080000;
                                                textBox8.BackColor = Color.LawnGreen;
                                            }

                                        //主电存在，
                                        int AC_light = (byteToUInt16(data[14], data[15]));
                                        if (AC_light > 8)
                                        {
                                            TestFlag |= 0x00010000;
                                            textBox10.Text = AC_light.ToString("0.0");//
                                            textBox10.BackColor = Color.LawnGreen;
                                        }


                                        //测试条件，主电在，不应急
                                        int VDD = (byteToUInt16(data[32], data[33]));
                                        int voltage =(int) (VDD * 0.01);
                                           // textBox34.Text = VDD.ToString();
                                            if (voltage > 20&& voltage<48&&((Alarm1 & 0x01) != 0x01)&&((errflag & 0x60) != 0x60))
                                            {
                                                TestFlag |= 0x00010000;
                                                TestFlag |= 0x00020000;
                                                textBox34.Text = voltage.ToString();//
                                                textBox34.BackColor = Color.LawnGreen;
                                            }



                                    }


; ;
                                        //供电状态
                                        if ((Alarm1 & 0x01) == 0x01)//判断主电还是备电
                                        {
                                            textBox12.Text = "备电";
                                        }
                                        else
                                        {
                                            textBox12.Text = "主电";
                                        }

                                        if ((Alarm1 & 0x08) == 0x08)//充电状态
                                        {
                                            textBox15.Text = "停止充电";
                                        }
                                        else
                                        {
                                            textBox15.Text = "充电中";
                                        }

                                        //  textBox13.Text = data[26].ToString("X2"); //Alarm2: 1字节，表示告警状态


                                        //EmerFlag: 应急状态, 
                                        if ((errflag & 0x60) == 0x60)//应急状态
                                        {
                                            textBox14.Text = "是";
                                            EmergencyFlag = 0x01;
                                            EmergencyOK = true;
                                            TestFlag |= 0x00000008;
                                            textBox14.BackColor = Color.LawnGreen;
                                         }                                                                              
                                        if ((EmergencyOK&&(EmergencyFlag & 0x01) == 0x01)&&((errflag & 0x60) != 0x60)&&(TestFlag> 0x00000008))
                                        {
                                            OverEmergency = true;
                                            EmergencyOK = false;
                                            EmergencyFlag = 0;
                                            TestFlag |= 0x00040000;
                                            textBox35.Text = "是";
                                            textBox35.BackColor = Color.LawnGreen;
                                          
                                        }
                                         
                                      
                                    
                                        if ((Alarm3 & 0x80) == 0x80)//判断电池电量是否充饱
                                        {
                                            textBox13.Text = "饱和";
                                        }
                                        else
                                        {
                                            textBox13.Text = "未充满";
                                        }
                                        FaultStatus(Alarm1, Alarm2, Alarm3);

                                    }
                                rec_i = 0;
                                    break;
                            default: rec_i = 0; break;  
                         }

                                             

                        }
                    else //
                    {
                      switch(rec_i)
                        {
                            case 0:
                             
                                if (q.Dequeue()== 0x50)//P
                                {
                                    rec_i = 1;
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 1:
                                if (q.Dequeue() == 0x53)//S
                                {
                                    rec_i = 2;
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 2:
                                if (q.Dequeue() == 0x2d)//-
                                {
                                    rec_i = 3;
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 3:
                                if (q.Dequeue() == 0x41)//A
                                {

                                    if (q.Count > 21)
                                    {
                                        rec_i = 4;
                                    }
                                    else
                                    {
                                        Thread.Sleep(50);
                                    }
                                    //rec_i = 4;
                                    //if (q.Count < 29) //26个字节
                                    //{
                                    //    Thread.Sleep(50);
                                    //    q.Clear();
                                    //}
                                }
                                else
                                {
                                    rec_i = 0;
                                }
                                break;
                            case 4:
                                OnLine = true;
                                vison[0] = 0x50;
                                vison[1] = 0x53;
                                vison[2] = 0x2d;
                                vison[3] = 0x41;
                                for (int i = 0; i < 22; i++)//36
                                {
                                    if (q.Count > 0)
                                      vison[4 + i] = q.Dequeue();
                                }

                             
                                string PowerVerision1 = byteTostring(vison);//接收到的版本信息                               
                              
                                int result = 0;                               
                           
                                textBox32.Text = goalPvison1;
                                goalPvison1 = byteTostring(vison).Substring(0, 18); //待对比的版本 
                                textBox33.Text = goalPvison1;//将INI读取到的版本信息显示 
                                string str1 = byteTostring(vison);//截取i之前的字符串
                                tbxSendStr.AppendText(str1 + Environment.NewLine);
                                result = String.Compare(goalPvison1, goalPvison1);
                              
                                if (result == 0)
                                {
                                    //if (q.Count > 0)
                                      //  q.Clear();
                                    timeflag = 0;
                                    QueryVersion = true;
                                    textBox33.BackColor = Color.LawnGreen;
                                    textBox32.BackColor = Color.LawnGreen;
                                }
                                else
                                {
                                    textBox33.BackColor = Color.Red;
                                    textBox32.BackColor = Color.Red;
                                }
                                rec_i = 0;
                                break;
                            default: rec_i = 0; break;


                        }
                   
                    }
              

                }
                catch
                {
                    throw;
                }




            }


        }

       /// <summary>
       /// 故障栏的测试项目
       /// </summary>
       /// 
       public void FaultStatus(byte Alarm1,byte Alarm2, byte Alarm3)
        {

            //第1个故障备电故障：Alarm1 Bit2:电池开路，0表示正常，1表示开路  备电故障
            if ((Alarm1 & 0x04) == 0x04)
            {
                textBox17.Text = "是";
                textBox17.BackColor = Color.LawnGreen;
                TestFlag |= 0x00000001;                 
            }
            //第2个结果：5V标定 0X02

            //第3个故障主电欠压：Bit4: 主电欠压，0表示正常，1表示欠压 AC 170 - 180
            if ((Alarm1 & 0x10) == 0x10)//
            {
                textBox22.Text = "是";
                textBox22.BackColor = Color.LawnGreen;
                TestFlag |= 0x00000004; 
            }
            //第4个结果：应急状态 0x08


            //第5项故障主电故障
            // Bit2:AC掉电，0表示正常，1表示掉电 小于170V，供备电，报AC掉电主电故障之一
            // Bit6:VDD异常，0表示正常，1表示VDD异常（AC-DC模块异常）
            if ((Alarm2 & 0x44)!=0)//
            {
                textBox18.Text = "是";
                textBox18.BackColor = Color.LawnGreen;
                TestFlag |= 0x00000010;
                //TestResult |= 0x10;

            }

            //第6项故障备电欠压
            if ((Alarm1 & 0x02) == 0x02)// 备电低于22.0V
            {
                textBox21.Text = "是";
                textBox21.BackColor = Color.LawnGreen;
                TestFlag |= 0x00000020;  
                //TestResult |= 0x20;
            }

                //第7项故障单节电池异常
                if ((Alarm3 & 0x08) == 0x08)//单节电池异常，随便一节即可
                {
                    textBox23.Text = "是";
                    textBox23.BackColor = Color.LawnGreen;
                    TestFlag |= 0x00000040;
                    //TestResult |= 0x40;
                }
          
           
            //第8项故障电池过温 
            if ((Alarm1 & 0x40) == 0x40)//电池过温 温度大于60℃
            {
                overtemp = true;
                textBox24.Text = "是";
                textBox24.BackColor = Color.LawnGreen;
                TestFlag |= 0x00000080;
                //TestResult |= 0x80;
            }
   
        }


       
        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {             
                //***正在接收状态指示。
                IsReceving = true;
                DoingHex = true;
                //读入收到的数据。
                Thread.Sleep(50);//延时一定时间，保证接收数据完整
                byte[] data = new byte[serialPort1.BytesToRead];
                int count = serialPort1.Read(data, 0, data.Length);
                for (int i = 0; i < count; i++)
                {
                    RecLen++;
                    q.Enqueue(data[i]);            
                }
            
                DoingHex = false;               
                while (DoingHex)
                {
                    //处理串口接收事件及其它系统消息。
                    Application.DoEvents();
                }
                IsReceving = false;  //***接收完成状态指示。

            }
            catch (Exception Err)
            {
                MessageBox.Show(Err.Message, "串口调试助手");
            }
        }
        /// <summary>
        /// 加载串口
        /// </summary>
        private void BindPort()
        {
          
            this.cbxPort.Items.Clear();
            try
            {
                //自动获取串行口名称
                foreach (string port in SerialPort.GetPortNames())
                {
                    this.cbxPort.Items.Add(port);
                }
                cbxPort.SelectedIndex = 0;
            }
            catch
            {
                MessageBox.Show("找不到通讯串口！", "串口调试助手");
            }
        }
        /// 获取校验和
        /// </summary>比如输入1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF，得到校验和30 
        /// <param name="Command"></param>
        /// <returns></returns>
        public static byte ADD8(byte[] b,byte length)
        {
            //int Len = b.Length;
            int Len = length;
            Int32 sum = 0;
            for (int i = 0; i < Len; i++)
            {
                sum += b[i];
            }
            //sum = sum % 256;
            //sum = ~sum + 1;
            byte a = (byte)sum;

            return a;
        }

        /// <summary>
        /// 将两个byte高八位和低八位组合成int
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public UInt16 byteToUInt16(byte DataH,byte DataL)
        {
            
            UInt16 value = 0;          
            value = Convert.ToUInt16(DataH << 8);
            value += Convert.ToUInt16(DataL);     
            return value;
        }
        /// <summary>
        /// 清除空格
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string DelSpace(string str)
        {
            string TempStr = string.Empty;
            int Len = str.Length;
            for (int i = 0; i < Len; i++)
            {
                if (str[i] != ' ')
                {
                    TempStr += str[i];
                }
            }
            //Hex 位数检查。
            Len = TempStr.Length;
            if (Len % 2 != 0)
            {
                TempStr = '0' + TempStr;
            }
            return TempStr;
        }
        //以为为串口常用函数
        /// <summary>
        /// 十六进制发送
        /// </summary>
        /// <param name="str"></param>
        private void SendAsHex(string str)
        {
            String txt = str;
            DelSpace(txt);
            int Len = txt.Length;
            //组包发送。
            byte[] send = new byte[Len / 2];
            for (int i = 0, j = 0; i < Len; i += 2, j++)
            {
                send[j] = Convert.ToByte(txt.Substring(i, 2), 16);
            }
            serialPort1.Write(send, 0, send.Length);
            SendLen = send.Length;
         
           
        }

        //在串口通讯过程中，经常要用到 16进制与字符串、字节数组之间的转换
        public static byte[] HexStringToBytes(string hs)
        {

            //string[] strArr = hs.Trim().Split(' ');

            //byte[] b = new byte[strArr.Length];
            //逐个字符变为16进制字节数据
            //for (int i = 0; i < strArr.Length; i++)
            //{
            //    b[i] = Convert.ToByte(strArr[i], 16);
            //}
            //按照指定编码将字节数组变为字符串
            //return b;
            byte[] byteArray = System.Text.Encoding.Default.GetBytes(hs);
            return byteArray;
        }


        /// <summary>
        /// 打开串口
        /// </summary>
        private void OpenPort()
        {
            //***避免串口死锁***
            //写超时，如果底层串口驱动效率问题，能有效的避免死锁。
            serialPort1.WriteTimeout = 1000;
            //读超时，同上。
            serialPort1.ReadTimeout = 1000;
            //回车换行。
            serialPort1.NewLine = "\r\n";
            //注册事件。
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(this.serialPort1_DataReceived);
            //***避免串口死锁***
           
            serialPort1.PortName = cbxPort.Text;
            serialPort1.BaudRate = int.Parse(cbxBaudRate.Text);
            serialPort1.DataBits = int.Parse(cbxDataBit.Text);
            serialPort1.Parity = (Parity)Enum.Parse(typeof(Parity), cbxParity.Text);
            serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cbxStopBit.Text);
            serialPort1.Open();
            label7.Text = cbxPort.Text + " " + cbxBaudRate.Text + " " + cbxDataBit.Text + " " + cbxParity.Text + " " + cbxStopBit.Text;


        }


/// 重新打开串口
/// </summary>
private void ReOpenPort()
        {

            if (isOpen == false)//如果串口处于关闭
            {
               
                try
                {
                    if (!String.IsNullOrEmpty(cbxPort.Text))
                    {

                        OpenPort();
                        timer1.Enabled = true;
                        dt = System.DateTime.Now;
                        // serialPort1.Open();//打开串口
                        isOpen = true;//串口打开标志位
                        btnCOM.Text = "串口已打开";//也就是说当前的打开的，需要按一下就会关闭
                        textBox32.ReadOnly = true;
                        textBox32.ReadOnly = true;
                        btnCOM.BackColor = Color.LawnGreen;
                        cbxPort.Enabled = false;
                        cbxBaudRate.Enabled = false;
                        cbxDataBit.Enabled = false;
                        cbxParity.Enabled = false;
                        cbxStopBit.Enabled = false;
                    }
                }
                catch (Exception Err)
                {
                    MessageBox.Show(Err.Message, "打开失败");
                }

            }
            else
            {
               
                try
                {
                    ClosePort();
                    timer1.Enabled = false;
                    isOpen = false;//串口打开标志位
                    btnCOM.Text = "串口已关闭";//也就是说当前的打开的，需要按一下就会关闭
                    textBox32.ReadOnly = false;
                    textBox32.ReadOnly = false;
                    btnCOM.BackColor = Color.Red;
                    cbxPort.Enabled = true;
                    cbxBaudRate.Enabled = true;
                    cbxDataBit.Enabled = true;
                    cbxParity.Enabled = true;
                    cbxStopBit.Enabled = true;
                }
                catch (Exception Err)
                {
                    MessageBox.Show(Err.Message, "打开失败");
                }


            }
    
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        private void ClosePort()
        {
            //安全关闭当前串口。
            //***避免串口死锁***
            //注销串口中断接收事件，避免下次再执行进来，造成死锁。
            serialPort1.DataReceived -= this.serialPort1_DataReceived;
            while (IsReceving)
            {
                //处理串口接收事件及其它系统消息。
                Application.DoEvents();
            }
            //现在没有死锁，可以关闭串口。
            serialPort1.Close();
            //***避免串口死锁***
        }
        /// <summary>
        /// 字符串转换为byte[]
        /// </summary>
        /// <param name="hexstring"></param>
        /// <returns></returns>
        private byte[] StringToByte(string hexstring)
        {
            byte[] bytes = System.Text.Encoding.Default.GetBytes(hexstring.Trim().Replace(" ", ""));
            return bytes;
        }

        /// <summary>
        /// byte[]转换成字符串
        /// </summary>
        /// <param name="byteArray"></param>
        /// <returns></returns>
        private string ByteToString(byte[] byteArray)
        {
            string str = System.Text.Encoding.Default.GetString(byteArray);
            return str;
        }

        /// <summary>
        /// 字符串转十六进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private byte[] StringToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
            {
                hexString += " ";
            }
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }
            return returnBytes;
        }




        /// <summary>
        /// 字节数组转十六进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string HexByteToString(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2")+" ";
                }
            }
            return returnStr;
        }

        //字符串转byte

        public Byte[] stringTobyte(string StringMessage)
        { 
            //string StringMessage = "How Are you?";   

            System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();

            Byte[] BytesMessage = ASCII.GetBytes(StringMessage);
            return BytesMessage;
        }

        //byte转字符串
        public string byteTostring(Byte[] BytesMessage)
        {            
            System.Text.ASCIIEncoding ASCII = new System.Text.ASCIIEncoding();

            String StringMessage = ASCII.GetString(BytesMessage);

            return StringMessage;
        } 








        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnCOM_Click(object sender, EventArgs e)
        {
            ReOpenPort();
            Start();
            //if (checkBox2.Checked)//如果是选中的,那就是锂电
            //    textBox32.Text = GetValue("Information", "Version1", newnamePath);
            //else
            //    textBox32.Text = GetValue("Information", "Version2", newnamePath);
            SendLen = 0;
            RecLen = 0;
            label4.Text = "0";
            label6.Text = "0";
        }

        private void cbxPort_SelectedIndexChanged(object sender, EventArgs e)
        {
           // ReOpenPort();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Emergency();//应急
            CheckCalibration();//进入产测，可以获取最全的返回结果。
        }

        #region CRC16校验
        /// <summary>
        /// CRC16校验
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        ///注意，输入字符串没有将CRC校验码算进去。
       
        public int CRC_GetModbus16(byte[] Data, int length)  //MODBUS CRC计算
        {
            int CRC0 = 0xFFFF, mid = 0;
            for (int i = length, Data_index = 0; i > 0; i--)
            {
                CRC0 = Data[Data_index] ^ CRC0;//把数据帧中的第一个字节的8位与CRC寄存器中的低字节进行异或运算，结果存回CRC寄存器
                for (int times = 0; times < 8; times++)
                {
                    mid = CRC0;
                    CRC0 = CRC0 >> 1;
                    if ((mid & 0x0001) == 0x0001)
                    { CRC0 = CRC0 ^ 0xA001; }
                }
                Data_index++;
            }
            return CRC0;
        }


        #endregion
        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {

        }


        #region 返回时间差
        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            string dateDiff = null;
            try
            {
                TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
                TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
                TimeSpan ts = ts1.Subtract(ts2).Duration();
                string hours = ts.Hours.ToString(), minutes = ts.Minutes.ToString(), seconds = ts.Seconds.ToString();
                if (ts.Hours < 10)
                {
                    hours = "0" + ts.Hours.ToString();
                }
                if (ts.Minutes < 10)
                {
                    minutes = "0" + ts.Minutes.ToString();
                }
                if (ts.Seconds < 10)
                {
                    seconds = "0" + ts.Seconds.ToString();
                }
                dateDiff = hours + ":" + minutes + ":" + seconds;
            }
            catch
            {

            }
            return dateDiff;
        }
        #endregion


        private void rtbxRecStr_TextChanged(object sender, EventArgs e)
        {

        }
        UInt32 onlinetime = 0;//时间统计
        byte timeflag = 0;
        bool StartTest = false;//开始测试的标志
        bool TestTime = false;//测试时间统计
        bool QueryVersion = false;//查询版本信息
        bool flagc = false;//用于询问测试完前面的项目，只询问一次的标志位
       
        private void timer1_Tick(object sender, EventArgs e)
        {
            string datatime= DateDiff(dt, System.DateTime.Now);   
            if (TestCount>0)
            {                
                float percentOK = (float)TestOK / (float)TestCount;
                textBox27.Text = percentOK.ToString("0%");
            }
            //textBox29.Text= RecDataLength.ToString();
            textBox26.Text = TestOK.ToString();//测试通过的数量显示
            label60.Text = datatime;//测试时间显示；
            label4.Text ="Send: "+ SendLen.ToString();//接收字节长度
            textBox25.Text = TestCount.ToString();
            //EB 90 03 02 00 FF E1 E0
            byte[] Check = new byte[8] {0xEB, 0x90, 0x03, 0x02, 0x00, 0xff, 0xE1,0XE0};//查询命令  
            //byte[] Vison = new byte[8] {0xEB, 0x90, 0x03, 0x01, 0xD1, 0x2E, 0x8D,0XEC};//简单版本查询
            byte[] Vison = new byte[8] { 0xEB, 0x90, 0x03, 0x01, 0xD3, 0x2E, 0x8C, 0X8C };//版本完全查询
            //EB 90 03 01 D3 2E 8C 8C 完整版
            //EB 90 03 01 D1 2E 8D EC 简约版
            label11.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss");
            label6.Text = "Rec: " + RecLen.ToString();//
            this.textBox31.Focus();
            if (StartTest)
            {
                int interval = (DateTime.Now - starttime).Seconds;
                textBox28.Text = interval.ToString();          
            }
            label68.Text = TestFlag.ToString("X2"); //如果检测到全部测试通过               
           if ((TestFlag == 0x000FFFFF) &&(!flagc))
            {
                flagc = true;//标志位，让通过结果只显示           
                StartTest = false;//测试时间终止                                  
                TestOK++;
                TestCount++;
                textBox16.Text = "PASS";
                textBox14.Text = "是";
                textBox14.BackColor = Color.LawnGreen;
                textBox16.BackColor = Color.LawnGreen;
                timeflag = 0;
            }
           
            switch (timeflag)
            { 
                case 0:  //自动打开串口。
                    OnLine = false;
                    if (!serialPort1.IsOpen)
                    {
                        btnCOM_Click(null, null); 
                    }                 
                    if (!QueryVersion)//先查询完整版版本信息
                    {
                        if(q.Count>0 )
                           q.Clear();
                        SendLen = Vison.Length;
                        if (serialPort1.IsOpen)
                        { serialPort1.Write(Vison, 0, Vison.Length); }
                           
                        
                    }
                    else//查询
                    {
                        if (checkBox1.Checked == true && RecDataLength != 0x21)
                        {

                            RecDataLength = 0;
                            if (q.Count > 0)
                                q.Clear();
                            CheckCalibration();//进入产测

                        }
                        else if (!StartEmergency && BatOnLine)//BatOnLine检测主电备电都存在
                        {
                            if (q.Count > 0)
                                q.Clear();
                            Emergency();//发送应急指令
                            if ((EmergencyFlag & 0x01) == 0x01)//已经获取到应急标志
                            {
                                StartEmergency = true;
                                OverEmergency = false;
                            }
                        }
                        else if(StartEmergency&& !OverEmergency && BatOnLine)
                        {
                            if (q.Count > 0)
                                q.Clear();
                            StopEmergency();
                        }
                        else
                        {
                            if (q.Count > 0)
                                q.Clear();
                            SendLen = Check.Length;
                            if (serialPort1.IsOpen)
                            {
                                serialPort1.Write(Check, 0, Check.Length);
                            }
                                
                         }                        
                         

                    }                       
                    timeflag = 1;                    
                    break;
                case 1:  
                    if(OnLine)//在线
                     {
                        onlinetime = 0;
                        label61.Text = "在线";
                        label61.BackColor = Color.LawnGreen;
                        if (!TestTime)
                        {
                            textBox16.Text = "Test...";
                            StartTest = true;
                            TestTime = true;
                            starttime = System.DateTime.Now;
                        }
                    }
                    else
                    {
                        if (++onlinetime >3) 
                        { 
                            onlinetime = 0;
                            label61.Text = "离线";
                            label61.BackColor = Color.Cyan;                           
                            if (StartTest)
                            {
                                StartTest = false;
                                TestCount++;
                                int interval = (DateTime.Now - starttime).Seconds;
                                textBox28.Text = interval.ToString();
                            }
                            flagc = false;
                            EmergencyFlag = 0;                            
                            TestTime = false;                            
                            TestFlag = 0;
                            StartEmergency = false;
                            OverEmergency = false;
                            EmergencyFlag = 0;                            
                            overtemp = false;                          
                            clean();//清屏幕
                            RecLen = 0;                            
                            RecDataLength = 0;
                            if (q.Count>0)//
                               q.Clear();
                        }
                    }
                    timeflag = 0;                         
                    break;             
                default: OnLine = false;
                         timeflag = 0;
                          break;

            }
         
          

        }

        public void Emergency()
        {
            //自动打开串口。
            if (!serialPort1.IsOpen)
            {
                btnCOM_Click(null, null);
            }
            //string txt = textBox29.Text;
            //0xEB 0x90 0x03 0x01 0x60 0x9F	0x39 0xC8
            string txt = "EB 90 03 01 60 9F 39 C8";
            //if(q.Count>0 && !CheckFlag)
           // q.Clear();
            string ba = DelSpace(txt); //删除空格                  
            SendAsHex(ba);
        }

        public void StopEmergency()
        {   
            //自动打开串口。
            if (!serialPort1.IsOpen)
            {
                btnCOM_Click(null, null);
            }
            //数据	0xEB 0x90  0x03 0x01 0x80 0x7F 0x71 0x80
            //EB  90  03  01  80  7F  71  80
            string txt = "EB 90 03 01 80 7F 71 80";
            string ba = DelSpace(txt); //删除空格  
            //if(q.Count>0 && !CheckFlag)
            //q.Clear();
            SendAsHex(ba);           

        }





        private void label12_Click(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void label7_Click(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            //Timeout = TimeCount;           
            //System.DateTime currentTime = new System.DateTime();
            //currentTime = System.DateTime.Now;
            //byte[] a = new byte[14];
            //a[0] = 85;
            //a[1] = 170;
            //a[2] = 1;
            //a[3] = 1;
            //a[4] = 7;
            //a[5] = Convert.ToByte(currentTime.Year % 2000);
            //a[6] = Convert.ToByte(currentTime.Month);
            //a[7] = Convert.ToByte(currentTime.Day);
            //a[8] = Convert.ToByte(currentTime.Hour);
            //a[9] = Convert.ToByte(currentTime.Minute);
            //a[10] = Convert.ToByte(currentTime.Second);
            //a[11] = Convert.ToByte(currentTime.DayOfWeek);

            //int CRC16 = CRC_GetModbus16(a, 12);
            //a[12] = Convert.ToByte(CRC16 & 0xff);//低
            //a[13] = Convert.ToByte(CRC16 >> 8);
            //Compare = a;
            ////自动打开串口。
            //if (!serialPort1.IsOpen)
            //{
            //    btnCOM_Click(null, null);
            //}
            //serialPort1.Write(a, 0, a.Length);
            ////加时间戳
            //currentTime = new System.DateTime();
            //currentTime = System.DateTime.Now;

            //string strY = "";
            //if (checkBox2.Checked)
            //{
            //    strY = "[" + currentTime.ToString("HH:mm:ss:fff") + "]" + "发->"; //不显示秒
            //}
            //strY += HexByteToString(a)+Environment.NewLine;


          // byte[] b = new byte[14];



        }

        private void panel4_Paint(object sender, PaintEventArgs e)
        {

        }

        private void tbxSendStr_TextChanged(object sender, EventArgs e)
        {

        }


        /// <summary>
        /// 逐个字节进行比较
        /// </summary>
        /// <param name="b1"></param>
        /// <param name="b2"></param>
        /// <returns></returns>
        private bool BytesCompare_Step(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null) return false;
            if (b1.Length != b2.Length) return false;
            for (int i = 0; i < b1.Length; ++i)
            {
                if (b1[i] != b2[i]) return false;
            }
            return true;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {

        }

  
        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void label12_Click_1(object sender, EventArgs e)
        {

        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            clean();
        }


        private void clean()
        {
            RecLen = 0;
            QueryVersion = false;
            textBox35.Text = String.Empty;
            textBox35.BackColor = Color.White;
            textBox34.Text = String.Empty;
            textBox34.BackColor = Color.White;
            tbxSendStr.Text = String.Empty;
            textBox1.Text = string.Empty;
            textBox1.BackColor = Color.White;
            textBox2.Text = string.Empty;
            textBox2.BackColor = Color.White;
            textBox3.Text = string.Empty;
            textBox3.BackColor = Color.White;
            textBox4.Text = string.Empty;
            textBox4.BackColor = Color.White;
            textBox5.Text = string.Empty;
            textBox5.BackColor = Color.White;
            textBox6.Text = string.Empty;
            textBox6.BackColor = Color.White;
            textBox7.Text = string.Empty;
            textBox7.BackColor = Color.White;
            textBox8.Text = string.Empty;
            textBox8.BackColor = Color.White;
            textBox9.Text = string.Empty;
            textBox9.BackColor = Color.White;
            textBox10.Text = string.Empty;
            textBox10.BackColor = Color.White;
            textBox11.Text = string.Empty;
            textBox11.BackColor = Color.White;
            textBox12.Text = string.Empty;
            textBox13.Text = string.Empty;
            textBox14.Text = string.Empty;
            textBox14.BackColor = Color.White;
            textBox15.Text = string.Empty;
            textBox16.Text = string.Empty;            
            textBox16.BackColor = Color.White;
            textBox17.Text = string.Empty;
            textBox17.BackColor = Color.White;
            textBox18.Text = string.Empty;
            textBox18.BackColor = Color.White;
            label68.Text = string.Empty;
            
            textBox20.Text = string.Empty;
          //  textBox20.BackColor = Color.White;
            textBox21.Text = string.Empty;
            textBox21.BackColor = Color.White;
            textBox22.Text = string.Empty;
            textBox22.BackColor = Color.White;
            textBox23.Text = string.Empty;
            textBox23.BackColor = Color.White;
            textBox24.Text = string.Empty;
            textBox24.BackColor = Color.White;
            //textBox25.Text = string.Empty;
            //textBox25.BackColor = Color.White;
            //textBox26.Text = string.Empty;
            //textBox26.BackColor = Color.White;
            //textBox27.Text = string.Empty;
            //textBox27.BackColor = Color.White;
            textBox30.Text = string.Empty;
            textBox30.BackColor = Color.White;
            textBox31.Text= string.Empty;
            textBox33.Text = string.Empty;
            textBox33.BackColor = Color.White;
            textBox32.BackColor = Color.White;           
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 一次性清空textbox、combobox中所有的内容
        /// </summary>
        public class Clear
        {
            public Clear(Form form, Panel panel)
            {
                foreach (Control cl in form.Controls)
                {
                    if (cl is ComboBox)
                    {
                        ComboBox cob = cl as ComboBox;
                        cob.SelectedIndex = -1;
                    }
                    else if (cl is TextBox)
                    {
                        TextBox tb = cl as TextBox;
                        tb.Text = string.Empty;
                    }
                }
                //清空的是容器上的控件
                foreach (Control cl in panel.Controls)
                {
                    if (cl is TextBox)
                    {
                        cl.Text = string.Empty;
                    }
                    else if (cl is ComboBox)
                    {
                        ComboBox cob = cl as ComboBox;
                        cob.SelectedIndex = -1;
                    }
                }
            }
        }

        private void panel5_Paint(object sender, PaintEventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void button4_Click_1(object sender, EventArgs e)
        {
           
        }
        /// <summary>
        /// 进入产测和退出产测命令，都是都一个命令，进入产测，恢复字节
        /// 总长度=LEN+5,
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryCalibration()
        {
            if (!serialPort1.IsOpen)
            {
                btnCOM_Click(null, null);
            }
            //EB 90 05 01 D2 EF DE 21 AC BB
            byte[] send = new byte[10] { 0xEB, 0x90, 0x05, 0x01, 0xD2, 0xEF, 0xDE, 0x21, 0xAC,0XBB };
            serialPort1.Write(send, 0, send.Length);
        }


        private void button5_Click(object sender, EventArgs e)
        {
            
           
            ushort volatage = 0;
            string strvolatage = "";
           
            if (!String.IsNullOrEmpty(textBox31.Text))         
            {
                //timer1.Stop();
                strvolatage = textBox31.Text;
                ushort.TryParse(strvolatage, out volatage);
                
                //EB  90  0B  01  DF  EF  DE  13  C4 00  00  00  00  FF  C7  5D  //16个字节
                byte[] Calibration0 = new byte[14];//12个需校验，最后两个位置用来存储CRC16校验
                byte[] Calibration1 = new byte[16];

                Calibration0[0] = 0X0B;//
                Calibration0[1] = 0X01; //
                Calibration0[2] = 0XDF;//
                Calibration0[3] = 0XEF; //
                Calibration0[4] = 0XDE;//  
                Calibration0[5] = (byte)(volatage >> 8);//5V dataH  
                Calibration0[6] = (byte)(volatage & 255); //5V dataL
                Calibration0[7] = 0;//ACH
                Calibration0[8] = 0;//
                Calibration0[9] = 0;//
                Calibration0[10] = 0;//
                Calibration0[11] = 0;//
                int CRC16 = CRC_GetModbus16(Calibration0, 12);
                Calibration0[12] = Convert.ToByte(CRC16 & 0xff);//低
                Calibration0[13] = Convert.ToByte(CRC16 >> 8);

                Calibration1[0] = 0xEB;
                Calibration1[1] = 0x90;
                for (short i=0;i<14;i++)
               {
                   Calibration1[2+i] = Calibration0[i];
               }
                if (!serialPort1.IsOpen)
                {
                    btnCOM_Click(null, null);
                }
                //if (q.Count > 0&&!CheckFlag)
                //    q.Clear();
                //标定5V命令
                if (q.Count > 0)
                  q.Clear();
                serialPort1.Write(Calibration1, 0, Calibration1.Length);                            
                CheckCalibration();//进入产测，可以获取最全的返回结果。
                //Thread.Sleep(200);                    // serialPort1.Write(send, 0, send.Length);
                //if (Rlen == 0x17)//如果不是产测将进产测
                //{
                //    QueryCalibration();
                //}
                //timer1.Start();
            }
            else
            {
                MessageBox.Show("5V输入不能为空！");
            }        


        //自动打开串口。
        //if (!serialPort1.IsOpen)
        //{
        //    btnCOM_Click(null, null);
        //}
        //if(textBox31.Text!=null)
        //{ 
        //    string txt = textBox31.Text;
        //    string ba = DelSpace(txt); //删除空格                  
        //    SendAsHex(ba);
        //}

    }

        /// <summary>
        /// 发送命令查询标定情况
        /// </summary>
        public void CheckCalibration()
        {
            //EB 90 05 01 D2 EF DE 21 AC BB 进入产测和退出产测的命令
            byte[] check4 = new byte[10] { 0xEB, 0x90, 0x05, 0x01, 0xD2, 0xEF, 0xDE, 0x21, 0xAC,0xBB };
            if (!serialPort1.IsOpen)
            {
                btnCOM_Click(null, null);
            }
            SendLen = check4.Length;
            serialPort1.Write(check4, 0, check4.Length);

        }

        private void panel7_Paint(object sender, PaintEventArgs e)
        {

        }

        private void textBox18_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox33_TextChanged(object sender, EventArgs e)
        {

        }

        private void label64_Click(object sender, EventArgs e)
        {

        }

        private void textBox31_TextChanged(object sender, EventArgs e)
        {
           
        }

        private void button6_Click(object sender, EventArgs e)
        {
            ushort volatage = 0;
            byte addCheck = 0;
            string strvolatage = "";
            if (!String.IsNullOrEmpty(textBox29.Text))
             //   if (textBox29.Text != "")
            {

                strvolatage = textBox29.Text;
                ushort.TryParse(strvolatage, out volatage);
                byte[] Calibration0 = new byte[8] { 0x01, 0xDF, 0xEF, 0xDE, 0x00, 0x00, 0x00, 0x00 };
                byte[] Calibration1 = new byte[12] { 0xEB, 0x90, 0x08, 0x01, 0xDF, 0xEF, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00 };//版本查询

                Calibration0[4] = 0;//ACH
                Calibration0[5] = 0;//ACL

                Calibration0[6] = (byte)(volatage >> 8);//5V dataH  
                Calibration0[7] = (byte)(volatage & 255); ;//5V dataL               

                addCheck = ADD8(Calibration0,8);

                Calibration1[7] = Calibration0[4];
                Calibration1[8] = Calibration0[5];
                Calibration1[9] = Calibration0[6];
                Calibration1[10] = Calibration0[7];
                Calibration1[11] = addCheck;
                if (!serialPort1.IsOpen)
                {
                    btnCOM_Click(null, null);
                }
               // if (q.Count > 0&&!CheckFlag)
               //     q.Clear();
                serialPort1.Write(Calibration1, 0, Calibration1.Length);
                Thread.Sleep(200);
                if (Rlen == 0x21)
                {
                   CheckCalibration();//标定查询
                }                

            }
            else
            {
                MessageBox.Show("AC输入不能为空！");
            }
        }

        private void textBox14_TextChanged(object sender, EventArgs e)
        {

        }

        private void groupBox4_Enter(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            BindPort();
        }

        private void textBox31_KeyDown(object sender, KeyEventArgs e)
        {
            //  if (textBox31.Enter)                  //enter键，显示数据
            if (e.KeyCode == Keys.Enter)           
            {
                button5_Click(null,null);
            }
           
        }

        private void checkBox1_CheckedChanged_1(object sender, EventArgs e)
        {
            if (checkBox1.Checked)//如果是选中的
            {


                textBox31.Enabled = false;
                textBox29.Enabled = false;
                button5.Enabled = false;
                button6.Enabled = false;
            }
            else 
            {                
               
                textBox31.Enabled = true;
                textBox29.Enabled = true;
                button5.Enabled = true;
                button6.Enabled = true;
            }
        }

        private void textBox20_TextChanged(object sender, EventArgs e)
        {

        }

   

        private void textBox32_TextChanged(object sender, EventArgs e)
        {

        }

        //private string GetValue(string section, string key, string IniFilePath)
        //{
        //    StringBuilder stringBuilder = new StringBuilder();
        //    GetPrivateProfileString(section, key, "", stringBuilder, 1024, IniFilePath);
        //    return stringBuilder.ToString();
        //}
        private void button7_Click(object sender, EventArgs e)
        {
            if (!File.Exists(newnamePath))//如果不存在该ini文件，则新建一个
            {
                FileStream fs = File.Create(newnamePath);
                fs.Close();
            }
            textBox33.Text = "";         
            string PowerVerision1 = textBox32.Text;
            WritePrivateProfileString("Information", "Version1", textBox32.Text, newnamePath);
            goalPvison1 = textBox32.Text;
     

            
        }

        private void label5_Click_1(object sender, EventArgs e)
        {

        }

        private void label5_Click_2(object sender, EventArgs e)
        {

        }
    }
}
